#ifndef FOC_H
#define FOC_H
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include "arm_math.h"

#define FOC_PI (3.1415926f)
#define FOC_2PI (6.2831852f)

#define TO_Q15(x) ((x) << 15)
#define Q15_TO(x) ((x) >> 15)
#define F32_TO_Q15(x) ((x) * 32768.0)
#define Q15_TO_F32(x) ((x) / 32768.0)

extern int sin_val_q15 ;
extern int cos_val_q15 ;
extern float sin_val_f32 ;
extern float cos_val_f32 ;

typedef struct
{
	uint32_t va;
	uint32_t vb;
	uint32_t vc;
	uint16_t initv;
	uint8_t len;
	int8_t direction;
	float k_f32,b_f32;
	int k_q15,b_q15;
	//int residue_e_q15[128][2];
	int angle_q15;
	float angle_f32;
	void (*set_va_pwm)(uint32_t x);
	void (*set_vb_pwm)(uint32_t x);
	void (*set_vc_pwm)(uint32_t x);
	void (*delay)(uint32_t x);
	uint32_t delay_x;
	uint8_t ready;
}foc_t;

/**
 * Clarke逆变换：将αβ轴分量转换为三相ABC分量
 * @param alpha α轴分量
 * @param beta  β轴分量
 * @param a     输出A相分量
 * @param b     输出B相分量
 * @param c     输出C相分量
 */
void inverse_clarke_q15(int64_t alpha, int64_t beta, int64_t *a, int64_t *b, int64_t *c);
void inverse_clarke_f32(float alpha, float beta, float *a, float *b, float *c);
float triangle_waves(float x);
int64_t triangle_waves_q15(int64_t x);
void svpwm_q15(int32_t d, int32_t q, int32_t theta, int32_t *a, int32_t *b, int32_t *c);

/**
 * Park逆变换：将dq轴分量转换为αβ轴分量
 * @param d     d轴分量
 * @param q     q轴分量
 * @param theta 电角度（弧度）
 * @param alpha 输出α轴分量
 * @param beta  输出β轴分量
 */
void inverse_park_q15(int32_t d, int32_t q, int32_t theta, int32_t *alpha, int32_t *beta);
void inverse_park_f32(float d, float q, float theta, float *alpha, float *beta);

int32_t machinery_angle_to_electric_angle_q15(foc_t *foc, int32_t angle);
float machinery_angle_to_electric_angle_f32(foc_t *foc, int32_t angle);
void foc_set_sector(foc_t *foc, uint8_t sector);
void foc_calibration(foc_t *foc,int *angle,int mid_angle);

/* 过零处理 */
int32_t zero_processing(int32_t target,int32_t fb,int32_t midfb);
#endif
